package cn.yunyichina.provider.pay.alipay.service.impl;

import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.pay.alipay.config.Alipay;
import cn.yunyichina.provider.pay.alipay.constant.ResponseEnum;
import cn.yunyichina.provider.pay.alipay.entity.AlipayAuth;
import cn.yunyichina.provider.pay.alipay.service.AlipayAuthService;
import cn.yunyichina.provider.pay.alipay.service.BaseService;
import cn.yunyichina.utils.commons.IdCardUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Lullaby on 2016/11/1.
 */
@Service
public class AlipayAuthServiceImpl extends BaseService implements AlipayAuthService {

    private static final Logger logger = LoggerFactory.getLogger(AlipayAuthServiceImpl.class);

    public ResponseObject getAlipayAuth(String data) {
        AlipayAuth auth = JsonUtils.parseObject(data, AlipayAuth.class);
        AlipayClient alipayClient = new DefaultAlipayClient(
                this.getConfig(Alipay.ALIPAY_GATEWAY_OPENAPI),
                auth.getAppId(),
                auth.getPrivateKey(),
                "json",
                "GBK",
                auth.getPublicKey(),
                auth.getSignType()
        );

        AlipaySystemOauthTokenRequest oauthTokenRequest = new AlipaySystemOauthTokenRequest();
        oauthTokenRequest.setCode(auth.getAuthCode());
        oauthTokenRequest.setGrantType("authorization_code");
        logger.info("AlipayAuthServiceImpl.getAlipayAuth.oauthTokenRequest -> {}", JSON.toJSONString(oauthTokenRequest));

        AlipaySystemOauthTokenResponse oauthTokenResponse;
        try {
            oauthTokenResponse = alipayClient.execute(oauthTokenRequest);
            logger.info("AlipayAuthServiceImpl.getAlipayAuth.oauthTokenResponse -> {}", JSON.toJSONString(oauthTokenResponse));

            if (!oauthTokenResponse.isSuccess()) {
                return new ResponseObject().buildResultCodeAndMessageAndResult(
                        ResponseEnum.ALIPAY_OAUTH_TOKEN_FAILURE.getCode(),
                        ResponseEnum.ALIPAY_OAUTH_TOKEN_FAILURE.getMessage(),
                        JSON.toJSONString(oauthTokenResponse)
                );
            }
        } catch (Exception e) {
            logger.error("AlipayAuthServiceImpl.getAlipayAuth.OauthToken.Exception", e);
            return new ResponseObject().buildResultCodeAndMessage(
                    ResponseEnum.ALIPAY_OAUTH_TOKEN_EXCEPTION.getCode(),
                    ResponseEnum.ALIPAY_OAUTH_TOKEN_EXCEPTION.getMessage()
            );
        }

        AlipayUserInfoShareResponse userInfoShareResponse;
        try {
            userInfoShareResponse = alipayClient.execute(new AlipayUserInfoShareRequest(), oauthTokenResponse.getAccessToken());
            logger.info("AlipayAuthServiceImpl.getAlipayAuth.userInfoShareResponse -> {}", JSON.toJSONString(userInfoShareResponse));

            if (!userInfoShareResponse.isSuccess()) {
                return new ResponseObject().buildResultCodeAndMessageAndResult(
                        ResponseEnum.ALIPAY_USER_INFO_FAILURE.getCode(),
                        ResponseEnum.ALIPAY_USER_INFO_FAILURE.getMessage(),
                        JSON.toJSONString(userInfoShareResponse)
                );
            }
        } catch (Exception e) {
            logger.error("AlipayAuthServiceImpl.getAlipayAuth.UserInfo.Exception", e);
            return new ResponseObject().buildResultCodeAndMessage(
                    ResponseEnum.ALIPAY_USER_INFO_EXCEPTION.getCode(),
                    ResponseEnum.ALIPAY_USER_INFO_EXCEPTION.getMessage()
            );
        }

        Map<String, String> result = new HashMap<>();
        result.put("access_token", oauthTokenResponse.getAccessToken());
        result.put("openid", oauthTokenResponse.getUserId());

        String cardNo = userInfoShareResponse.getCertNo();
        String realName = userInfoShareResponse.getUserName();
        String mobile = userInfoShareResponse.getMobile();
        String gender = userInfoShareResponse.getGender();
        String cardType = userInfoShareResponse.getCertType();

        if (!StringUtils.isEmpty(cardNo)) {
            result.put("card_no", cardNo);
        }
        if (!StringUtils.isEmpty(realName)) {
            result.put("real_name", realName);
        }
        if (!StringUtils.isEmpty(mobile)) {
            result.put("mobile", mobile);
        }
        if (!StringUtils.isEmpty(cardType)) {
            result.put("card_type", cardType);
        }
        if (!StringUtils.isEmpty(gender)) {
            result.put("gender", gender.toUpperCase());
        } else {
            if (!StringUtils.isEmpty(cardType) && !StringUtils.isEmpty(cardNo) && cardType.equals("0")) {
                result.put("gender", IdCardUtils.getGenderByIdCard(cardNo));
            } else {
                result.put("gender", "U");
            }
        }

        return new ResponseObject().buildResultObject(result);
    }

}
